package designModal;

import org.aopalliance.intercept.Invocation;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 *
 * 动态代理
 *
 * Author: shen qi han
 * Date: 2022/4/8 下午5:14
 */
public class ProxyByDynamicMain {

    interface ITask{
        public void doTask();
    }

    class Worker implements ITask {
        @Override
        public void doTask() {
            System.out.println("working....");
        }
    }

    class Boss implements ITask{
        @Override
        public void doTask() {
            System.out.println("meeting....");
        }
    }

    /**
     *动态代理 代理类
     */
    class ProxyHandler implements InvocationHandler{
        private Object object;

        /**
         * instance object need class and class's interface and handler
         * @param object
         * @return
         */
        public Object getInstance(Object object) {
            this.object = object;
            Class<?> clazz = object.getClass();
            return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
        }

        @Override
        public Object invoke(Object o, Method method, Object[] args) throws Throwable {
            System.out.println("before invoke " + method.getName());
            // mark here invoke this.object
            Object invoke = method.invoke(this.object, args);
            System.out.println("after invoke " + method.getName());
            return invoke;
        }
    }

    public void demo(){
        ITask task = new Worker();
        ITask task2 = new Boss();

        // target class and target interface and handler interface instance
        ITask work = (ITask) new ProxyHandler().getInstance(task);
        ITask boss = (ITask) new ProxyHandler().getInstance(task2);

        // do proxy target's target method
        work.doTask();
        System.out.println("=========================");
        boss.doTask();
    }

    public static void main(String[] args) {
        System.getProperties().setProperty("sum.misc.ProxyGenerator.saveGeneratedFiles", "true");

        ProxyByDynamicMain main = new ProxyByDynamicMain();
        main.demo();
    }


}
